package main

import (
	"context"
	"fmt"
	"internal-net-bridge-server/internal/billing"
	"io"
	"log"
	"net/http"
	"os"
	"os/signal"
	"path/filepath"
	"syscall"
	"time"

	"github.com/gin-gonic/gin"
	"golang.org/x/net/http2"
	"golang.org/x/net/http2/h2c"

	"internal-net-bridge-server/internal/api"
	"internal-net-bridge-server/internal/config"
	"internal-net-bridge-server/internal/middleware"
	"internal-net-bridge-server/internal/models"
	"internal-net-bridge-server/internal/services"
	"internal-net-bridge-server/internal/tunnel"
	httpProto "internal-net-bridge-server/internal/tunnel/protocols/http"
	"internal-net-bridge-server/internal/utils"
)

func main() {
	// 初始化日志：同时输出到控制台和文件
	setupLogging()

	log.Println("🚀 启动 Internal Net Bridge 服务器...")

	// 加载配置文件
	configPath := "config.yaml"
	if err := config.LoadConfig(configPath); err != nil {
		log.Printf("⚠️ 配置加载失败: %v", err)
		log.Println("📋 使用默认配置继续启动...")
	}

	// 初始化数据库
	if err := config.InitDatabase(); err != nil {
		log.Printf("⚠️ 数据库连接失败: %v", err)
		log.Printf("🔄 将使用模拟模式运行服务器")
	} else {
		defer config.CloseDatabase()

		// 执行数据库迁移
		if err := config.AutoMigrate(); err != nil {
			log.Printf("⚠️ 数据库迁移失败: %v", err)
		} else {
			// 创建默认管理员账户
			if err := config.CreateDefaultAdmin(); err != nil {
				log.Printf("⚠️ 创建默认管理员失败: %v", err)
			}
		}
	}

	// 检查并清理端口占用
	log.Println("🔧 检查端口占用情况...")
	portsToCheck := []int{config.GetHTTPPort(), config.GetTunnelPort()} // 从配置文件读取端口
	if err := utils.CheckAndClearPorts(portsToCheck); err != nil {
		log.Printf("⚠️  端口清理警告: %v", err)
		log.Println("📋 继续启动服务...")
	}

	// 初始化配置服务（仅在数据库连接成功时）
	var appConfig *models.AppConfig
	var dnsService *services.DNSPodService
	var configService *services.ConfigService

	if config.DB != nil {
		configService = services.NewConfigService()

		// 初始化默认配置
		if err := configService.InitializeDefaultConfigs(); err != nil {
			log.Printf("⚠️  初始化默认配置失败: %v", err)
		}

		// 🔥 从数据库获取配置（唯一配置源）
		log.Printf("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
		log.Printf("🔍 配置源: 数据库 (tb_config)")
		log.Printf("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")

		var err error
		appConfig, err = configService.GetAppConfig()
		if err != nil {
			log.Printf("❌ 从数据库获取配置失败: %v", err)
			log.Fatal("无法启动服务器")
		}

		log.Printf("✅ 数据库配置已加载")

		// 打印数据库配置参数
		configService.PrintAllConfigs()

		// 验证数据库配置
		if err := configService.ValidateConfig(); err != nil {
			log.Printf("⚠️  数据库配置验证失败: %v", err)
			log.Println("📋 某些功能可能无法正常工作")
		}
	} else {
		log.Printf("⚠️  数据库未连接，使用默认配置运行")
		// 使用默认配置
		appConfig = &models.AppConfig{
			DNS: models.DNSConfig{
				Enabled: false,
			},
			Tunnel: models.TunnelConfig{
				PortRangeStart: 10000,
				PortRangeEnd:   20000,
			},
			DomainRouter: models.DomainRouterConfig{
				Enabled: false,
				Port:    80,
			},
			Tencent: models.TencentConfig{},
		}
	}

	// 初始化服务
	tunnelService := services.NewTunnelService()

	// 🆕 初始化DNSPod服务（从数据库配置）
	log.Printf("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
	log.Printf("🔍 DNSPod配置检查（来源: 数据库 tb_config）")
	log.Printf("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
	log.Printf("   DNS.Enabled:  %v", appConfig.DNS.Enabled)
	log.Printf("   DNS.Domain:   %s", appConfig.DNS.Domain)
	log.Printf("   DNS.PublicIP: %s", appConfig.DNS.PublicIP)

	// 脱敏显示密钥
	secretIDMasked := "未设置"
	if appConfig.Tencent.SecretID != "" {
		if len(appConfig.Tencent.SecretID) > 8 {
			secretIDMasked = appConfig.Tencent.SecretID[:4] + "****" + appConfig.Tencent.SecretID[len(appConfig.Tencent.SecretID)-4:]
		} else {
			secretIDMasked = "****"
		}
	}
	secretKeyMasked := "未设置"
	if appConfig.Tencent.SecretKey != "" {
		if len(appConfig.Tencent.SecretKey) > 8 {
			secretKeyMasked = appConfig.Tencent.SecretKey[:4] + "****" + appConfig.Tencent.SecretKey[len(appConfig.Tencent.SecretKey)-4:]
		} else {
			secretKeyMasked = "****"
		}
	}
	log.Printf("   Tencent.SecretID:  %s", secretIDMasked)
	log.Printf("   Tencent.SecretKey: %s", secretKeyMasked)
	log.Printf("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")

	// 检查每个条件并给出详细提示
	if !appConfig.DNS.Enabled {
		log.Printf("⚠️  DNSPod未启用（dns.enabled=false）")
		log.Printf("💡 如需启用，请在数据库中执行:")
		log.Printf("   UPDATE tb_config SET config_value = 'true' WHERE config_key = 'dns.enabled';")
		log.Printf("💡 或运行配置脚本: mysql -u root -p tunnel_db < server/update_dns_config.sql")
	} else if appConfig.DNS.Domain == "" {
		log.Printf("❌ DNS域名未配置（dns.domain为空）")
		log.Printf("💡 请在数据库中执行:")
		log.Printf("   UPDATE tb_config SET config_value = 'niuma946.com' WHERE config_key = 'dns.domain';")
	} else if appConfig.DNS.PublicIP == "" {
		log.Printf("❌ 公网IP未配置（dns.public_ip为空）")
		log.Printf("💡 请在数据库中执行:")
		log.Printf("   UPDATE tb_config SET config_value = '你的公网IP' WHERE config_key = 'dns.public_ip';")
		log.Printf("💡 获取公网IP: curl ifconfig.me")
	} else if appConfig.Tencent.SecretID == "" || appConfig.Tencent.SecretKey == "" {
		log.Printf("❌ 腾讯云密钥未配置")
		if appConfig.Tencent.SecretID == "" {
			log.Printf("   tencent.secret_id 为空")
			log.Printf("💡 请在数据库中执行:")
			log.Printf("   UPDATE tb_config SET config_value = '你的SecretId' WHERE config_key = 'tencent.secret_id';")
		}
		if appConfig.Tencent.SecretKey == "" {
			log.Printf("   tencent.secret_key 为空")
			log.Printf("💡 请在数据库中执行:")
			log.Printf("   UPDATE tb_config SET config_value = '你的SecretKey' WHERE config_key = 'tencent.secret_key';")
		}
		log.Printf("💡 获取腾讯云密钥: https://console.cloud.tencent.com/cam/capi")
		log.Printf("💡 或运行配置脚本: mysql -u root -p tunnel_db < server/update_dns_config.sql")
	} else {
		// 所有条件满足，初始化DNSPod
		log.Printf("🌐 正在初始化DNSPod服务...")
		log.Printf("   ├─ 域名: %s", appConfig.DNS.Domain)
		log.Printf("   ├─ 公网IP: %s", appConfig.DNS.PublicIP)

		var err error
		dnsService, err = services.NewDNSPodServiceWithCredentials(
			appConfig.DNS.Domain,
			appConfig.DNS.PublicIP,
			appConfig.Tencent.SecretID,
			appConfig.Tencent.SecretKey,
		)
		if err != nil {
			log.Printf("❌ DNSPod服务初始化失败: %v", err)
			log.Printf("💡 请检查:")
			log.Printf("   1. 腾讯云密钥是否正确")
			log.Printf("   2. 域名是否已在DNSPod中添加")
			log.Printf("   3. 网络连接是否正常")
			dnsService = nil
		} else {
			log.Printf("✅ DNSPod服务初始化成功")
			// 🔥 关键：将DNSPod服务设置到TunnelService
			tunnelService.SetDNSService(dnsService)
			log.Printf("✅ DNSPod服务已设置到TunnelService")
			log.Printf("🎉 创建隧道时将自动创建DNS记录！")
		}
	}
	log.Printf("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")

	// 初始化隧道管理器
	tunnelManager := tunnel.NewTunnelManager(tunnelService)

	// 🆕 初始化上传缓存管理器
	uploadCacheManager := httpProto.NewUploadCacheManager()

	// 🔥 从数据库加载现有的active隧道到内存
	if err := tunnelManager.LoadActiveTunnels(); err != nil {
		log.Printf("⚠️  加载隧道失败: %v", err)
	}

	// 初始化域名路由器（如果启用）- 使用数据库配置
	var domainRouter *services.DomainRouter
	if appConfig.DomainRouter.Enabled {
		log.Printf("🌐 启用域名路由器在端口 %d", appConfig.DomainRouter.Port)

		domainRouter = services.NewDomainRouter(appConfig.DomainRouter.Port, dnsService)
		if err := domainRouter.Start(); err != nil {
			log.Printf("⚠️  域名路由器启动失败: %v", err)
		} else {
			log.Printf("✅ 域名路由器启动成功")
			// 将域名路由器设置到隧道管理器
			tunnelManager.SetDomainRouter(domainRouter)
		}
	}

	// 🔥 旧TCP隧道服务器已禁用（改用QUIC）
	// go tunnelManager.StartTunnelServer()
	log.Printf("⚠️  旧TCP隧道服务器已禁用，请使用QUIC连接（端口9443）")

	// ⚠️ HTTP/2隧道服务器已废弃（改用QUIC）
	log.Printf("⚠️  HTTP/2隧道服务器已废弃，现在使用QUIC（端口9443）")

	// 🚀🚀🚀 启动 QUIC 隧道服务器
	log.Printf("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
	log.Printf("🚀 启动 QUIC 隧道服务器...")

	// 加载 TLS 配置
	quicTLSConfig, err := tunnel.LoadQUICTLSConfig()
	if err != nil {
		log.Printf("❌ 加载QUIC TLS配置失败: %v", err)
		log.Printf("⚠️  QUIC隧道服务器将不会启动")
	} else {
		// 创建 QUIC 隧道服务器（监听 9443 端口）
		quicServer, err := tunnel.NewQUICTunnelServer(":9443", quicTLSConfig, tunnelManager)

		//开启计费
		billingManager := quicServer.GetBillingManager()
		billingManager.Enable()

		// TODO 立即触发限制(测试使用)
		billingManager.SetUserQuota("", 2,
			billing.PaymentTypeQRCode,
			"https://pay.example.com/checkout",
			"ORDER-TEST-001")

		if err != nil {
			log.Printf("❌ 创建QUIC隧道服务器失败: %v", err)
		} else {
			// 🔥 设置QUIC服务器到TunnelManager（重要：让公共端口处理器可以使用）
			tunnelManager.SetQUICServer(quicServer)
			
			// 🆕 设置上传缓存管理器到TunnelManager
			tunnelManager.SetUploadCacheManager(uploadCacheManager)

			// 在独立 goroutine 中启动 QUIC 服务器
			go func() {
				if err := quicServer.Start(); err != nil {
					log.Printf("❌ QUIC服务器错误: %v", err)
				}
			}()

			log.Printf("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
			log.Printf("✨ 🎉 QUIC 隧道服务器启动成功！🎉 ✨")
			log.Printf("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
			log.Printf("")
			log.Printf("📊 QUIC 性能优势:")
			log.Printf("   ✅ 连接建立: 0-RTT (vs HTTP/2: 3-RTT)")
			log.Printf("   ✅ 丢包恢复: 独立Stream (vs HTTP/2: 全局阻塞)")
			log.Printf("   ✅ 连接迁移: 无缝切换 (vs HTTP/2: 断开重连)")
			log.Printf("   ✅ 并发能力: 10000+ Streams")
			log.Printf("")
			log.Printf("🔧 技术规格:")
			log.Printf("   ├─ 监听端口: 9443 (UDP)")
			log.Printf("   ├─ 协议: QUIC")
			log.Printf("   ├─ TLS: 1.3 (ALPN: h3-tunnel)")
			log.Printf("   ├─ 最大并发: 10000 Streams")
			log.Printf("   ├─ 保活间隔: 30s")
			log.Printf("   └─ 空闲超时: 2min")
			log.Printf("")
			log.Printf("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
		}
	}

	// 设置Gin路由
	r := gin.Default()

	// 设置UTF-8字符集中间件（修复中文乱码）
	r.Use(func(c *gin.Context) {
		c.Writer.Header().Set("Content-Type", "application/json; charset=utf-8")
		c.Next()
	})

	// 添加CORS中间件
	r.Use(func(c *gin.Context) {
		c.Header("Access-Control-Allow-Origin", "*")
		c.Header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
		c.Header("Access-Control-Allow-Headers", "Content-Type, Authorization")

		if c.Request.Method == "OPTIONS" {
			c.AbortWithStatus(204)
			return
		}

		c.Next()
	})

	// 创建API处理器
	// 🔥 关键修复：传入已配置好DNSPod的 tunnelService
	apiHandler := api.NewAPIHandler(tunnelManager, tunnelService)
	authHandler := api.NewAuthHandler(configService)
	// 🆕 上传缓存API处理器
	uploadCacheHandler := api.NewUploadCacheHandler(uploadCacheManager)

	// 公开API路由 (不需要认证)
	public := r.Group("/api")
	{
		// 认证相关路由
		auth := public.Group("/auth")
		{
			auth.POST("/send-code", authHandler.SendVerificationCode)
			auth.POST("/verify-code", authHandler.VerifyCode)
			auth.GET("/validate-token", authHandler.ValidateToken) // 移到公开路由
		}
	}

	// 应用配置路由
	r.GET("/app/config", authHandler.GetAppConfig)
	r.GET("/api/client/config", authHandler.GetClientConfig)

	// 需要认证的API路由
	api := r.Group("/api")

	// 使用统一认证中间件 - 根据配置自动处理认证逻辑
	api.Use(middleware.UnifiedAuthMiddleware())
	log.Println("🔐 使用统一认证中间件 (根据配置自动启用/禁用认证)")

	{
		// 认证相关路由 (需要token)
		auth := api.Group("/auth")
		{
			auth.GET("/user-info", authHandler.GetUserInfo)
			auth.POST("/logout", authHandler.Logout)
			auth.POST("/refresh-token", authHandler.RefreshToken)
		}

		// 隧道相关路由 (保持原有接口)
		api.POST("/create/tunnel", apiHandler.CreateTunnel)
		api.GET("/tunnels", apiHandler.ListTunnels)
		api.GET("/tunnels/:id", apiHandler.GetTunnel)
		api.PUT("/tunnels/:id", apiHandler.UpdateTunnel)
		api.DELETE("/tunnels/:id", apiHandler.DeleteTunnel)
		api.PATCH("/tunnels/:id/status", apiHandler.UpdateTunnelConnectionStatus) // 新增状态更新路由
	}

	// 🚀 HTTP/2混合模式路由（无需认证，因为客户端通过隧道ID验证）
	tunnelGroup := r.Group("/tunnel")
	{
		// HTTP/2响应接收端点
		http2Handler := tunnelManager.GetHTTP2Handler()
		tunnelGroup.POST("/response/:requestID", http2Handler.HandleHTTP2Response)
		
		// HTTP/2连接健康检查端点
		tunnelGroup.GET("/ping", func(c *gin.Context) {
			c.JSON(200, gin.H{"message": "pong", "protocol": c.Request.Proto})
		})
		
		log.Println("🚀 [HTTP/2混合模式] 响应接收端点已注册: POST /tunnel/response/:requestID")
		log.Println("🚀 [HTTP/2混合模式] 健康检查端点已注册: GET /tunnel/ping")
	}

	// 🆕 上传缓存路由（客户端拉取用，无需认证）
	uploadCacheGroup := r.Group("/api/upload/cache")
	{
		uploadCacheGroup.GET("/:requestID", uploadCacheHandler.GetCachedUpload)
		uploadCacheGroup.GET("/:requestID/meta", uploadCacheHandler.GetMeta)
		uploadCacheGroup.GET("/:requestID/chunk/:chunkIndex", uploadCacheHandler.GetChunk)
		uploadCacheGroup.DELETE("/:requestID", uploadCacheHandler.DeleteCache)
		uploadCacheGroup.GET("/stats", uploadCacheHandler.GetCacheStats)
		
		log.Println("📦 [上传缓存] 客户端拉取端点已注册:")
		log.Println("   ├─ GET /api/upload/cache/:requestID - 获取完整上传")
		log.Println("   ├─ GET /api/upload/cache/:requestID/meta - 获取元数据")
		log.Println("   ├─ GET /api/upload/cache/:requestID/chunk/:chunkIndex - 获取分片")
		log.Println("   ├─ DELETE /api/upload/cache/:requestID - 删除缓存")
		log.Println("   └─ GET /api/upload/cache/stats - 统计信息")
	}

	// 管理员路由
	admin := api.Group("/admin")
	admin.Use(middleware.AdminMiddleware())
	{
		admin.GET("/users", authHandler.GetUserList)
	}

	// 🚀🚀🚀 启动HTTP/2服务器（h2c，明文HTTP/2）
	log.Println("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
	log.Println("🚀 HTTP/2服务器启动在端口 8080 (h2c - 明文HTTP/2)")
	log.Println("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
	log.Println("📋 API接口文档:")
	log.Println("   认证接口:")
	log.Println("     POST /api/auth/send-code      - 发送验证码")
	log.Println("     POST /api/auth/verify-code    - 验证码登录")
	log.Println("     GET  /api/auth/validate-token - 验证token")
	log.Println("     GET  /api/auth/user-info      - 获取用户信息")
	log.Println("     POST /api/auth/logout         - 登出")
	log.Println("   应用配置:")
	log.Println("     GET  /app/config              - 获取应用配置")
	log.Println("   隧道接口:")
	log.Println("     POST /api/create/tunnel       - 创建隧道")
	log.Println("     GET  /api/tunnels             - 获取隧道列表")
	log.Println("   HTTP/2混合模式:")
	log.Println("     POST /tunnel/response/:requestID - HTTP/2响应接收")
	log.Println("     GET  /tunnel/ping                - 连接健康检查")
	log.Println("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")

	// 🔥 创建HTTP/2服务器（支持h2c - 明文HTTP/2）
	h2s := &http2.Server{
		MaxConcurrentStreams:  250,
		MaxReadFrameSize:      1024 * 1024, // 1MB
		IdleTimeout:           300 * time.Second,
		MaxUploadBufferPerConnection: 1024 * 1024, // 1MB
		MaxUploadBufferPerStream:     1024 * 1024, // 1MB
	}

	server := &http.Server{
		Addr:         ":8080",
		Handler:      h2c.NewHandler(r, h2s), // 🔥 包装Gin路由，支持HTTP/2
		ReadTimeout:  60 * time.Second,
		WriteTimeout: 300 * time.Second, // 🔥 增加到5分钟，支持大文件分片传输
		IdleTimeout:  120 * time.Second,
	}

	// 🔥 优雅关闭处理
	go func() {
		if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
			log.Fatalf("❌ HTTP/2服务器启动失败: %v", err)
		}
	}()

	log.Println("✅ HTTP/2服务器启动成功！")
	log.Println("   ├─ 协议: HTTP/2 (h2c) + HTTP/1.1")
	log.Println("   ├─ 最大并发Stream: 250")
	log.Println("   ├─ 最大帧大小: 1MB")
	log.Println("   └─ 空闲超时: 300s")
	log.Println("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")

	// 🔥 等待中断信号以优雅关闭服务器
	quit := make(chan os.Signal, 1)
	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
	<-quit

	log.Println("🛑 服务器正在关闭...")

	// 5秒超时优雅关闭
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	if err := server.Shutdown(ctx); err != nil {
		log.Fatal("服务器强制关闭:", err)
	}

	log.Println("✅ 服务器已优雅关闭")
}

// setupLogging 配置日志输出：同时输出到控制台和文件
// 支持命令行运行、GoLand运行、GoLand调试等所有场景
func setupLogging() {
	// 创建logs目录
	logsDir := "logs"
	if err := os.MkdirAll(logsDir, 0755); err != nil {
		fmt.Printf("⚠️ 创建日志目录失败: %v\n", err)
		return
	}

	// 生成日志文件名（带时间戳）
	timestamp := time.Now().Format("20060102_150405")
	logFileName := filepath.Join(logsDir, fmt.Sprintf("server_%s.log", timestamp))

	// 打开日志文件
	logFile, err := os.OpenFile(logFileName, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
	if err != nil {
		fmt.Printf("⚠️ 打开日志文件失败: %v\n", err)
		return
	}

	// 注意：不要defer logFile.Close()，因为日志文件需要在整个程序运行期间保持打开
	// 程序退出时操作系统会自动关闭文件

	// 创建MultiWriter：同时写入控制台和文件
	multiWriter := io.MultiWriter(os.Stdout, logFile)

	// 设置log包的输出
	log.SetOutput(multiWriter)
	log.SetFlags(log.LstdFlags) // 包含日期和时间

	// 打印日志配置信息
	log.Printf("📝 日志配置完成:")
	log.Printf("   ├─ 控制台输出: 启用")
	log.Printf("   ├─ 文件输出: 启用")
	log.Printf("   └─ 日志文件: %s", logFileName)
	log.Println("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
}
